package com.lvtu.monitor.utils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;

import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.FilterBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.sort.SortBuilder;

import com.alibaba.fastjson.JSONObject;
import com.lvmama.com.lvtu.common.utils.UUIDGenerator;

/**
 * @Title: ElasticUtils.java
 * @Package com.lvtu.monitor.utils
 * @Description: TODO
 * @author dengcheng
 * @date 2015-5-15 下午1:41:51
 * @version V1.0.0
 */
public class ElasticUtils {
	private static volatile ElasticUtils instance;
	private TransportClient client;

	public ElasticUtils() {
		init();
	}

	public void init() {
		// 配置你的es,现在这里只配置了集群的名,默认是elasticsearch,跟服务器的相同

		// 这里可以同时连接集群的服务器,可以多个,并且连接服务是可访问的
		String elasticClusterName = Constants.getInstance().getValue(
				"elastic.cluster.name");
		Settings settings = ImmutableSettings.settingsBuilder()
				.put("cluster.name", elasticClusterName).build();
		String[] elasticUrls = Constants.getInstance().getValue("elastic.url").split(",");
		client = new TransportClient(settings);
		
		for (String elasticUrl : elasticUrls) {
			String elasticHost = elasticUrl.split(":")[0];
			int elasticPort = Integer.valueOf(elasticUrl.split(":")[1]);
			client.addTransportAddress(new InetSocketTransportAddress(
					elasticHost, elasticPort));
		}

	}

	public class IndexPage {
		int page;
		int rows;

		QueryBuilder builder;

		public int getPage() {
			return page;
		}

		public int getRows() {
			return rows;
		}

		public void setPage(int page) {
			this.page = page;
		}

		public void setRows(int rows) {
			this.rows = rows;
		}

		public QueryBuilder getBuilder() {
			return builder;
		}

		public void setBuilder(QueryBuilder builder) {
			this.builder = builder;
		}

		/**
		 * 获得开始查询位置
		 * 
		 * @Description: TODO
		 * @author dengcheng
		 * @date 2015-5-22 下午5:33:35
		 */
		public int getFrom() {
			return (page - 1) * rows;
		}

		/**
		 * 获得查询条数
		 * 
		 * @Description: TODO
		 * @author dengcheng
		 * @date 2015-5-22 下午5:33:49
		 */
		public int getSize() {
			return rows;
		}
	}

	public static ElasticUtils getInstance() {
		if (instance == null) {
			synchronized (ElasticUtils.class) {
				if (instance == null) {
					instance = new ElasticUtils();
				}
			}
		}
		return instance;
	}

	/**
	 * 以json方式提交索引
	 * @param index		索引库名称
	 * @param type		索引类型
	 * @param json		json格式数据
	 * @throws InterruptedException
	 * @throws ExecutionException
	 * @author dengcheng
	 * @date 2015-5-15 下午1:59:54
	 */
	public void putIndex(String index, String type, String json)
			throws InterruptedException, ExecutionException {
		UUIDGenerator gen = new UUIDGenerator();
		IndexRequest indexRequest = new IndexRequest(index, type, gen
				.generate().toString()).source(json);
		client.index(indexRequest).get();
	}

	/**
	 * 统计匹配的索引个数
	 * @param index		索引库名称
	 * @param query		查询条件
	 * @param filter	筛选条件
	 * @return
	 */
	public <T> Long countIndex(String index, QueryBuilder query,
			FilterBuilder filter) {
		SearchResponse response = client.prepareSearch(index).setFrom(0)
				.setQuery(query).setPostFilter(filter)
				.setSearchType(SearchType.COUNT).execute().actionGet();
		long hitNum = response.getHits().getTotalHits();
		return hitNum;

	}
	
	/**
	 * 批量获取索引值
	 * @param index		索引库名称
	 * @param clazz		匹配的对象
	 * @param query		查询条件
	 * @param filter	筛选条件
	 * @param sort		排序条件
	 * @param start		开始位置
	 * @param size		获取条数
	 * @return
	 */
	public <T> List<T> queryIndex(String index, Class<T> clazz,
			QueryBuilder query, FilterBuilder filter,
			SortBuilder sort, int start, int size) {
		SearchResponse response = client.prepareSearch(index).setFrom(start)
				.setQuery(query).setPostFilter(filter).setSize(size)
				.setExplain(true).addSort(sort).execute().actionGet();
		List<T> exlist = new ArrayList<T>();
		for (SearchHit hit : response.getHits().getHits()) {
			String value = hit.getSourceAsString();
			exlist.add(JSONObject.parseObject(value, clazz));

		}
		return exlist;
	}
	
	/**
	 * 
	* @Description: TODO 
	* @author dengcheng 
	* @date 2015-6-11 上午11:40:01
	* @param params 查询参数
	* @param tpName 定义的模板名称
	* @param clazz 返回对象clazz 
	* @param sources 模板源码
	 */
	public <T> List<T> queryByTemplate(Map<String,Object> params,String tpName,Class<T> clazz,String sources){
		client.preparePutIndexedScript("mustache", tpName,sources).get();
		SearchResponse response = client.prepareSearch()
		        .setTemplateName(tpName)
		        .setTemplateType(ScriptService.ScriptType.INDEXED)
		        .setTemplateParams(params).setFrom(0).setSize(100).setExplain(true)
		        .get();
		
		List<T> exlist = new ArrayList<T>();
		for (SearchHit hit : response.getHits().getHits()) {
			String value = hit.getSourceAsString();
			exlist.add(JSONObject.parseObject(value, clazz));
		}
		return exlist;
	}

}
